<?php

spl_autoload_register(function($class){
    Base::loader($class);
});

class Base
{
    private static $path;

    public function __get($name)
    {
        $method='get'.ucfirst($name);
        if(method_exists($this,$method)) return $this->$method();
    }

    public function __set($name,$value)
    {
        $method='set'.ucfirst($name);
        if(method_exists($this,$method)) return $this->$method($value);
        elseif(!property_exists($this,$name)) $this->$name=$value;
    }

    public static function loader($class)
    {
        $className=ucfirst($class);
        if(!class_exists($className)){
            if($file=self::searchFile($class)) require_once($file);
        }
    }

    public static function __callStatic($name,$params=array())
    {
        if($params && is_array($params) && sizeof($params)==1 && isset($params[0])){
            $params=$params[0];
        }

        $class=ucfirst($name);
        if($path=self::$path) $file=$path.SEP.$class.'.php';
        else{
            if(!$path=self::searchFile($name,FRAMEWORK)) $path=self::searchFile($name,APP);
            if(!$path){
                Sys::app()->error='Не удалось найти класс '.$class.' Убедитесь, что файл '.$class.'.php существует';
                return false;
            }
            $file=$path;
        }

        if(!is_file($file)){
            self::loader($class);
        }else{
            require_once($file);
        }

        if(class_exists($class)){
            $baseDir=dirname($file);
            $baseDirParts=array_filter(explode(SEP,$baseDir));
            $baseClassDirName=end($baseDirParts);
            if($baseClassDirName=='classes'){
                $baseDir=dirname($baseDir);
                $baseDirParts=array_filter(explode(SEP,$baseDir));
                $baseClassDirName=end($baseDirParts);
            }
            Sys::app()->scripts=BASEURL.'framework'.SEP.'views'.SEP.'scripts'.SEP.$baseClassDirName.'.js';
            return new $class($params);
        }else{
            Sys::app()->error='Неудачная попытка загрузить класс '.$name.'. Убедитесь, что файл '.$file.' Существует и содержит корректное определение класса '.$class;
            return false;
        }
    }

    public static function checkAttributes($attributes=array())
    {
        $attributes=array_filter($attributes);
        return $attributes;
    }

    public function parseString($string)
    {
        if($string==='' || $string==='/' || $string===' ') return '';
        $string=str_replace('%20',' ',$string);
        return (trim(trim($string),'/'));
    }

    public function searchFile($name,$path=BASE_DIR)
    {
        if(!$path && $name){
            $name=self::parsePath($name);
            $path=str_replace(SEP.$name,'',$name);
        }
        if(!strpos($name,'.php')) $file=$name.'.php';
        else $file=$name;
        $path=SEP.self::parseString($path);

        $result='';
        $dir=glob($path.'/*');

        foreach($dir as $something){
            if(is_file($something) && ($something==$path.SEP.$file || $something==$path.SEP.ucfirst($file) || $something==$path.SEP.lcfirst($file))){
                $result=$something;
                break;
            }elseif(is_dir($something)){
                if($result=self::searchFile($name,$something)) break;
            }
        }

        return $result;
    }

    public static function parsePath($className)
    {
        $className=str_replace('.php','',$className);
        if(strpos($className,SEP)===false) return $className;
        $className=array_filter(explode(SEP,$className));
        return end($className);
    }

    protected function checkView($view='')
    {
        if(!$view) $view='index';
        if(!strpos($view,'.php')) $view.='.php';
        $className=str_replace('Controller','',get_class($this));

        $path=$this->path ? $this->path : $this->searchFile($className);
        $path=str_replace(SEP.$className.'.php','',$path);

        if($path==CONTROLLERS || $path.SEP==CONTROLLERS) $path=dirname($path);
        if($path==APP || $path.SEP==APP) $file=$path.SEP.'views'.SEP.'html'.SEP.lcfirst($className).SEP.$view;
        else $file=$path.'views'.SEP.lcfirst($className).SEP.$view;

        if(is_file($file)) return $file;
        else{
            Sys::app()->error='Не удалось найти представление для обработчика '.$className;
            return false;
        }
    }

    protected function renderView($view='',$params=array())
    {
        if(!$params && is_array($view)){
            $params=$view;
            $view=false;
        }
        if(!$view) $view=$this->view;
        if(!is_file($view)) $view=$this->checkView($view);
        if(!is_file($view)) return false;

        if($params){
            foreach($params as $name=>$value){
                $$name=$value;
            }
        }

        ob_start();
            require_once($view);
            $view=ob_get_contents();
        ob_end_clean();

        return $view;
    }
}